using AutoMapper;
using B.S.Data.MES.API.Applications.AICustomerService.Commands;
using B.S.Data.MES.API.Services;
using B.S.Domain.AICustomerService;
using B.S.Domain.Dto.AICustomerServiceDTO;
using B.S.Infratrctrue;
using B.S.Requst;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Yitter.IdGenerator;

namespace B.S.Data.MES.API.Applications.AICustomerService.CommandHandlers
{
    /// <summary>
    /// AI对话命令处理器
    /// </summary>
    public class AIConversationCommandHandler : 
        IRequestHandler<AIConversationCommand, APIRequst<AIConversationResponseDTO>>,
        IRequestHandler<GetConversationHistoryCommand, APIRequst<APIPageing<List<ConversationHistoryDTO>>>>,
        IRequestHandler<SatisfactionRatingCommand, APIRequst<int>>,
        IRequestHandler<CloseConversationCommand, APIRequst<int>>
    {
        private readonly IBaseRepository<AIConversation> _conversationRepository;
        private readonly IBaseRepository<AIKnowledgeBase> _knowledgeRepository;
        private readonly IDataQueryService _dataQueryService;
        private readonly IMapper _mapper;
        private readonly ILogger<AIConversationCommandHandler> _logger;
        private readonly IHttpClientFactory _httpClientFactory;

        public AIConversationCommandHandler(
            IBaseRepository<AIConversation> conversationRepository,
            IBaseRepository<AIKnowledgeBase> knowledgeRepository,
            IDataQueryService dataQueryService,
            IMapper mapper,
            ILogger<AIConversationCommandHandler> logger,
            IHttpClientFactory httpClientFactory)
        {
            _conversationRepository = conversationRepository;
            _knowledgeRepository = knowledgeRepository;
            _dataQueryService = dataQueryService;
            _mapper = mapper;
            _logger = logger;
            _httpClientFactory = httpClientFactory;
        }

        /// <summary>
        /// 处理AI对话请求
        /// </summary>
        public async Task<APIRequst<AIConversationResponseDTO>> Handle(AIConversationCommand request, CancellationToken cancellationToken)
        {
            var stopwatch = Stopwatch.StartNew();

            try
            {
                // 1. 创建对话记录
                var conversation = new AIConversation
                {
                    ConversationId = (int)YitIdHelper.NextId(),
                    SessionId = request.Request.SessionId,
                    UserId = request.Request.UserId,
                    UserName = request.Request.UserName,
                    UserMessage = request.Request.UserMessage,
                    MessageType = request.Request.MessageType,
                    ClientIP = request.Request.ClientIP,
                    DeviceInfo = request.Request.DeviceInfo,
                    Status = "active",
                    CreateTime = DateTime.Now,
                    CreateName = request.Request.UserName ?? "系统用户",
                    isDel = false
                };

                // 2. 智能匹配知识库答案（使用智能重试机制）
                var aiResponse = await GenerateAIResponseWithRetry(request.Request.UserMessage);
                conversation.AIResponse = aiResponse.Response;
                conversation.CategoryTag = aiResponse.Category;

                // 3. 记录处理时间
                stopwatch.Stop();
                conversation.ProcessingTime = (int)stopwatch.ElapsedMilliseconds;

                // 4. 保存对话记录
                await _conversationRepository.Add(conversation);

                // 5. 构建响应
                var response = new AIConversationResponseDTO
                {
                    ConversationId = conversation.ConversationId,
                    SessionId = conversation.SessionId,
                    AIResponse = conversation.AIResponse,
                    ProcessingTime = conversation.ProcessingTime ?? 0,
                    CategoryTag = conversation.CategoryTag,
                    Suggestions = aiResponse.Suggestions,
                    CreateTime = conversation.CreateTime ?? DateTime.Now
                };

                return new APIRequst<AIConversationResponseDTO>
                {
                    Code = RequstCode.成功,
                    Msg = "AI对话处理成功",
                    Data = response
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "AI对话处理失败: {Message}", ex.Message);
                return new APIRequst<AIConversationResponseDTO>
                {
                    Code = RequstCode.失败,
                    Msg = $"AI对话处理失败: {ex.Message}",
                    Data = null!
                };
            }
        }

        /// <summary>
        /// 获取对话历史
        /// </summary>
        public async Task<APIRequst<APIPageing<List<ConversationHistoryDTO>>>> Handle(GetConversationHistoryCommand request, CancellationToken cancellationToken)
        {
            try
            {
                var query = _conversationRepository.GetAll();

                // 按条件筛选
                if (!string.IsNullOrEmpty(request.SessionId))
                    query = query.Where(x => x.SessionId == request.SessionId);

                if (request.UserId.HasValue)
                    query = query.Where(x => x.UserId == request.UserId);

                if (request.StartTime.HasValue)
                    query = query.Where(x => x.CreateTime >= request.StartTime);

                if (request.EndTime.HasValue)
                    query = query.Where(x => x.CreateTime <= request.EndTime);

                // 排序
                query = query.OrderByDescending(x => x.CreateTime);

                // 分页
                var total = await query.CountAsync(cancellationToken);
                var conversations = await query
                    .Skip((request.PageIndex - 1) * request.PageSize)
                    .Take(request.PageSize)
                    .ToListAsync(cancellationToken);

                var historyList = _mapper.Map<List<ConversationHistoryDTO>>(conversations);

                var pageResult = new APIPageing<List<ConversationHistoryDTO>>
                {
                    Total = (int)Math.Ceiling((double)total / request.PageSize),
                    TotalCount = total,
                    Data = historyList
                };

                return new APIRequst<APIPageing<List<ConversationHistoryDTO>>>
                {
                    Code = RequstCode.成功,
                    Msg = "获取对话历史成功",
                    Data = pageResult
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取对话历史失败: {Message}", ex.Message);
                return new APIRequst<APIPageing<List<ConversationHistoryDTO>>>
                {
                    Code = RequstCode.失败,
                    Msg = $"获取对话历史失败: {ex.Message}",
                    Data = new APIPageing<List<ConversationHistoryDTO>>
                    {
                        Total = 0,
                        TotalCount = 0,
                        Data = new List<ConversationHistoryDTO>()
                    }
                };
            }
        }

        /// <summary>
        /// 处理满意度评价
        /// </summary>
        public async Task<APIRequst<int>> Handle(SatisfactionRatingCommand request, CancellationToken cancellationToken)
        {
            try
            {
                var conversation = await _conversationRepository.GetById(request.Rating.ConversationId);
                if (conversation == null)
                {
                    return new APIRequst<int>
                    {
                        Code = RequstCode.失败,
                        Msg = "对话记录不存在",
                        Data = 0
                    };
                }

                conversation.SatisfactionRating = request.Rating.SatisfactionRating;
                conversation.UserFeedback = request.Rating.UserFeedback;
                conversation.IsResolved = request.Rating.IsResolved;
                conversation.UpdateTime = DateTime.Now;
                conversation.UpdateName = "用户评价";

                await _conversationRepository.Update(conversation);

                return new APIRequst<int>
                {
                    Code = RequstCode.成功,
                    Msg = "满意度评价成功",
                    Data = 1
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "满意度评价失败: {Message}", ex.Message);
                return new APIRequst<int>
                {
                    Code = RequstCode.失败,
                    Msg = $"满意度评价失败: {ex.Message}",
                    Data = 0
                };
            }
        }

        /// <summary>
        /// 关闭对话
        /// </summary>
        public async Task<APIRequst<int>> Handle(CloseConversationCommand request, CancellationToken cancellationToken)
        {
            try
            {
                var conversations = await _conversationRepository.GetAll()
                    .Where(x => x.SessionId == request.SessionId && x.Status == "active")
                    .ToListAsync(cancellationToken);

                foreach (var conversation in conversations)
                {
                    conversation.Status = "closed";
                    conversation.UpdateTime = DateTime.Now;
                    conversation.UpdateName = "系统关闭";
                    if (!string.IsNullOrEmpty(request.CloseReason))
                    {
                        conversation.UserFeedback = $"关闭原因: {request.CloseReason}";
                    }
                }

                if (conversations.Any())
                {
                    await _conversationRepository.UpdateRange(conversations);
                }

                return new APIRequst<int>
                {
                    Code = RequstCode.成功,
                    Msg = "对话关闭成功",
                    Data = conversations.Count
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "关闭对话失败: {Message}", ex.Message);
                return new APIRequst<int>
                {
                    Code = RequstCode.失败,
                    Msg = $"关闭对话失败: {ex.Message}",
                    Data = 0
                };
            }
        }

        /// <summary>
        /// 智能重试机制 - 自动尝试不同格式
        /// </summary>
        private async Task<(string Response, string? Category, List<string>? Suggestions)> GenerateAIResponseWithRetry(string userMessage, int maxRetries = 3)
        {
            var attempts = 0;
            var originalMessage = userMessage;
            
            while (attempts < maxRetries)
            {
                try
                {
                    attempts++;
                    _logger.LogInformation("AI响应生成尝试 {Attempt}/{MaxRetries}: {Message}", attempts, maxRetries, userMessage);
                    
                    var result = await GenerateAIResponse(userMessage);
                    
                    // 如果成功获得有效响应
                    if (!string.IsNullOrEmpty(result.Response) && result.Response != "抱歉，我暂时无法理解您的问题，请您稍后再试或联系人工客服。")
                    {
                        _logger.LogInformation("AI响应生成成功，尝试次数: {Attempts}", attempts);
                        return result;
                    }
                    
                    // 如果是第一次尝试失败，尝试重新组织问题
                    if (attempts == 1)
                    {
                        userMessage = ReformulateQuestion(originalMessage);
                        _logger.LogInformation("重新组织问题: {NewMessage}", userMessage);
                        continue;
                    }
                    
                    // 如果是第二次尝试失败，尝试简化问题
                    if (attempts == 2)
                    {
                        userMessage = SimplifyQuestion(originalMessage);
                        _logger.LogInformation("简化问题: {NewMessage}", userMessage);
                        continue;
                    }
                    
                    // 最后一次尝试，返回结果
                    if (attempts == maxRetries)
                    {
                        _logger.LogWarning("AI响应生成达到最大重试次数，返回当前结果");
                        return result;
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "AI响应生成尝试 {Attempt} 失败: {Message}", attempts, ex.Message);
                    
                    if (attempts == maxRetries)
                    {
                        return ("抱歉，系统暂时繁忙，请稍后再试或联系人工客服。", "error", 
                                new List<string> { "稍后重试", "联系客服", "查看帮助" });
                    }
                }
            }
            
            return ("系统响应超时，请稍后再试。", "timeout", new List<string> { "重新提问", "联系客服" });
        }
        
        /// <summary>
        /// 重新组织问题 - 添加上下文和关键词
        /// </summary>
        private string ReformulateQuestion(string originalQuestion)
        {
            var keywords = new Dictionary<string, string[]>
            {
                { "工单", new[] { "生产工单", "制造订单", "生产计划", "工作订单" } },
                { "物料", new[] { "产品物料", "原材料", "材料信息", "库存物料" } },
                { "客户", new[] { "客户信息", "客户资料", "客户管理", "客户数据" } },
                { "仓库", new[] { "仓库管理", "库存信息", "仓储数据", "库房状态" } },
                { "生产线", new[] { "产线信息", "生产线管理", "产线状态", "制造线" } }
            };
            
            foreach (var keyword in keywords)
            {
                if (originalQuestion.Contains(keyword.Key))
                {
                    return $"{keyword.Value.First()} {originalQuestion}";
                }
            }
            
            return $"查询 {originalQuestion}";
        }
        
        /// <summary>
        /// 简化问题 - 提取核心关键词
        /// </summary>
        private string SimplifyQuestion(string originalQuestion)
        {
            var coreKeywords = new[] { "工单", "物料", "客户", "仓库", "生产线", "库存", "订单", "产品", "材料" };
            
            foreach (var keyword in coreKeywords)
            {
                if (originalQuestion.Contains(keyword))
                {
                    return keyword;
                }
            }
            
            // 如果没有找到关键词，返回简化的查询
            var words = originalQuestion.Split(new[] { ' ', '，', '。', '？', '！' }, StringSplitOptions.RemoveEmptyEntries);
            return words.Length > 0 ? words[0] : "数据查询";
        }

        /// <summary>
        /// 生成AI响应
        /// </summary>
        private async Task<(string Response, string? Category, List<string>? Suggestions)> GenerateAIResponse(string userMessage)
        {
            try
            {
                _logger.LogInformation("开始处理用户消息: {Message}", userMessage);

                // 1. 先从知识库中查找匹配的答案
                var knowledgeMatches = await SearchKnowledgeBase(userMessage);

                if (knowledgeMatches.Any())
                {
                    var bestMatch = knowledgeMatches.First();
                    
                    // 更新知识库使用次数
                    bestMatch.UsageCount++;
                    bestMatch.LastUsedTime = DateTime.Now;
                    await _knowledgeRepository.Update(bestMatch);

                    var suggestions = knowledgeMatches.Skip(1).Take(3)
                        .Select(x => x.Title).ToList();

                    return (bestMatch.Answer, bestMatch.Category, suggestions);
                }

                // 2. 尝试从实际数据中查询回答
                _logger.LogInformation("知识库未匹配，尝试查询实际数据");
                var dataQueryResult = await _dataQueryService.QueryDataByQuestion(userMessage);

                if (dataQueryResult.Success && !string.IsNullOrEmpty(dataQueryResult.Answer))
                {
                    _logger.LogInformation("数据查询成功，返回查询结果");
                    return (dataQueryResult.Answer, dataQueryResult.DataType, dataQueryResult.Suggestions);
                }

                // 3. 如果数据查询也没有结果，使用默认回复
                _logger.LogInformation("数据查询无结果，使用默认回复");
                var defaultResponse = await GenerateDefaultResponse(userMessage);
                return (defaultResponse, "general", new List<string> 
                { 
                    "查看系统数据概览", 
                    "了解系统功能", 
                    "联系技术支持" 
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "生成AI响应失败: {Message}", ex.Message);
                return ("抱歉，我暂时无法理解您的问题，请您稍后再试或联系人工客服。", "error", null);
            }
        }

        /// <summary>
        /// 搜索知识库
        /// </summary>
        private async Task<List<AIKnowledgeBase>> SearchKnowledgeBase(string userMessage)
        {
            // 简单的关键词匹配，实际项目中可以使用更复杂的NLP算法
            var keywords = userMessage.Split(' ', '，', '。', '？', '！', '、')
                .Where(x => !string.IsNullOrWhiteSpace(x) && x.Length > 1)
                .ToList();

            var query = _knowledgeRepository.GetAll()
                .Where(x => x.IsEnabled);

            foreach (var keyword in keywords)
            {
                query = query.Where(x => x.Question.Contains(keyword) || 
                                        x.Answer.Contains(keyword) || 
                                        x.Title.Contains(keyword) ||
                                        (x.Tags != null && x.Tags.Contains(keyword)));
            }

            return await query
                .OrderByDescending(x => x.Priority)
                .ThenByDescending(x => x.UsageCount)
                .Take(5)
                .ToListAsync();
        }

        /// <summary>
        /// 生成默认响应
        /// </summary>
        private async Task<string> GenerateDefaultResponse(string userMessage)
        {
            // 这里可以集成ChatGPT、文心一言等AI服务
            // 目前使用简单的规则回复

            var lowerMessage = userMessage.ToLower();

            if (lowerMessage.Contains("你好") || lowerMessage.Contains("hello"))
                return "您好！我是AI智能客服，很高兴为您服务。请问有什么可以帮助您的吗？";

            if (lowerMessage.Contains("谢谢") || lowerMessage.Contains("感谢"))
                return "不客气！如果您还有其他问题，随时可以咨询我。";

            if (lowerMessage.Contains("再见") || lowerMessage.Contains("拜拜"))
                return "再见！祝您生活愉快，有问题随时联系我们。";

            if (lowerMessage.Contains("人工客服") || lowerMessage.Contains("转人工"))
                return "正在为您转接人工客服，请稍等...";

            // 默认回复
            return "我理解您的问题，但可能需要更多信息才能给出准确答案。您可以：\n1. 详细描述一下具体情况\n2. 联系我们的人工客服\n3. 查看帮助文档";
        }
    }
}
